

import { _path, _g, _text } from "./svg.js"
import { _o, isMatrix, _dis, _mid, plainMatrix, _moveDis } from "../math/index.js"
import { linkCrossPoints, edgeExtensionPoints, edgeExtensionCrossPoints } from '../algorithm/link.js'
import { _colors } from "../color/index.js"
import { _show, _mirrorPath, _borderPoints, _colorProps, _mergeProps, _merge } from '../common/index.js'
import { _motion } from './motion.js'
import { _pathMode, _polyline, _lines, _ray, _rayOne, _points, _link } from "./pathMode.js"
import { _circle } from './circle.js'
import { genLabel } from '../common/labels.js'
import { _mark } from "./mark.js"
import { _fill } from "./fill.js"
import { _mirrorColor } from '../common/index.js'


// 标注
const _labels = ({ points = [], render }, opitons = {}, props = {}) => {
    let { type } = props
    let o = _o(points)
    return points.map((t, index) => {
        let text = genLabel(type, index)
        let pos = _moveDis(t, o, 10)
        let [x, y] = pos
        return _text({
            shape: 'text',
            x, y,
            text: render ? render(index) : text
        }, {
            name: 'text',
            fontSize: 12,
            textAnchor: 'middle',
            dominantBaseline: 'middle',
            ...props,
            ...opitons
        })
    })
}



// 边
const _edge = ({ pathMode, points, curve }, props) => {
    let path = _pathMode({ pathMode, points, curve })

    return _path(path, {
        stroke: 'red',
        fill: 'none',
        ...props
    })
}


const _dashLines = (points, props) => {
    return _path(_lines(points), props)
}

// 边延长线
const _edgeExtension = ({ points, edgeExtension }, props) => {

    let gs = []
    let { crossPoints, labels } = edgeExtension
    let ps = edgeExtensionPoints(points, edgeExtension.iterNum)

    gs.push(_dashLines(ps, { ...props, ...edgeExtension }))

    // gs.push(_path(_points(ps, edgeExtension.r), _merge(props, edgeExtension)))

    if (crossPoints || labels) {
        let cps = edgeExtensionCrossPoints(points)
        // 交点
        if (crossPoints) {
            gs.push(_path(_points(cps, edgeExtension.r), _merge(props, edgeExtension)))
        }

        // 标注
        if (labels) {
            gs.push(_labels({ points: cps }, {}, {
                stroke: 'blue'
            }))
        }
    }
    return gs
}
const _vertex = ({ points, vertex }, props) => {
    let { one, r } = vertex
    if (one) {
        return _path(_circle({ o: points[0], r }), _merge(props, vertex))
    }
    return _path(_points(points, r), _merge(props, vertex))
}
const _excircle = ({ points, excircle }, props) => {
    let o = _o(points)
    let r = _dis(o, points[0])
    let circle = _circle({ o, r })
    return _path(circle, _merge(props, excircle))
}
const _incircle = ({ points, incircle }, props) => {
    let o = _o(points)
    let r = _dis(o, _mid.apply(null, points.slice(0, 2)))
    let circle = _circle({ o, r })
    return _path(circle, _merge(props, incircle))
}
const _radius = ({ points, radius }, props) => {
    let { one } = radius
    if (one) {
        return _path(_rayOne(points), _merge(props, radius))
    }
    return _path(_ray(points), _merge(props, radius))
}

export const _path2 = (options, props) => {
    let { name, points, pathMode, curve, mirror, vertex, centre, excircle, incircle, radius,
        labels, linkCross, links, motion, edgeExtension, edge, mark, fill } = options
    if (isMatrix(points)) {
        let mirrorPoints = _borderPoints(points)
        let n = points.length
        // let color = mirror && mirror.color ? mirror : options.color
        let color = mirror && mirror.color ? _mirrorColor(mirror) : options.color
        let _props = _colorProps(color, n)
        let arr = points.map((t, i) => {
            let newProps = _merge(props, _props(i))
            return _path2({
                ...options,
                points: t,
                mirrorPoints,
                edge: {
                    ...edge,
                    ...newProps
                }
            }, newProps)
        })
        return _g(arr)
    }


    let gs = []
    // 填充
    if (_show(fill)) {
        gs[gs.length] = _fill({ points, fill, curve }, _merge(props, fill))
    }


    // 边
    if (edge) {
        if (_show(edge)) {
            gs[gs.length] = _edge({ pathMode, points, curve }, _merge(props, edge))
        }
    } else {
        gs[gs.length] = _edge({ pathMode, points, curve }, props)
    }

    // 边延长线
    if (_show(edgeExtension)) {
        gs[gs.length] = _edgeExtension({ points, edgeExtension }, props)
    }
    // 顶点
    if (_show(vertex)) {
        gs[gs.length] = _vertex({ points, vertex }, props)
    }
    // 
    // 中点
    if (_show(centre)) {
        let o = _o(points)
        gs[gs.length] = _path(_points([o], centre.r), _merge(props, centre))
    }
    // 外切圆
    if (_show(excircle)) {
        gs[gs.length] = _excircle({ points, excircle }, props)
    }
    // 内切圆
    if (_show(incircle)) {
        gs[gs.length] = _incircle({ points, incircle }, props)
    }


    // 半径
    if (_show(radius)) {
        gs[gs.length] = _radius({ points, radius }, props)
    }

    // 标注
    if (_show(labels)) {
        gs[gs.length] = _labels({ points }, labels, _merge(props, labels))
    }


    // 连线交叉点
    if (_show(linkCross)) {
        if (points.length > 50) {
            // '截取了50个节点，linkCross'
            points = points.slice(0, 50)
        }

        let lcps = linkCrossPoints(points)
        gs[gs.length] = _path(_points(lcps), _merge(props, linkCross))

    }

    // 连线 与 交叉点
    if (_show(links)) {
        gs[gs.length] = _path(_link(points), links)
        if (links.crossPoints) {
            let lcps = linkCrossPoints(points)
            gs[gs.length] = _path(_points(lcps), _merge({ fill: 'red' }, links))
        }
    }


    // 标注
    if (_show(mark)) {
        gs[gs.length] = _mark({ points, mark }, { ...props, ...mark })
    }


    // 镜像
    if (_show(mirror)) {
        gs.push(..._mirrorPath(_path2, options, props))
    }

    // motion
    if (_show(motion)) {
        gs[gs.length] = _motion({ ...motion, points })
    }

    return _g(gs, {
        name
    })

}


export const createPathFn = (genPoints) => {
    return (options, props) => {
        let points = (typeof genPoints === 'function') ? genPoints(options) : genPoints
        return _path2({
            ...options,
            points
        }, {
            stroke: 'blue',
            fill: 'none',
            ...props
        })
    }
}

// 彩色
export const colorPath = (matrix, options, props) => {
    let { color, alpha, oneLine = false, motion, o } = options
    let _fn = (colors) => {
        let children = matrix.map((t, i) => {
            let newProps = {
                ...props,
                fill: 'none',
                stroke: Array.isArray(colors) ? colors[i] : colors,
            }
            return _path2({
                ...options,
                points: t,
                motion: null
            }, newProps)
        })
        // motion
        if (_show(motion)) {
            let { type, speed } = motion
            if (type === 'rotate') {
                children.push(_animateRotate(o, speed))
            }
        }
        return _g(children)
    }
    if (oneLine) {
        // 单色 一笔画
        let points = plainMatrix(matrix)
        return _path2({
            ...options,
            points
        }, {
            stroke: 'red',
            fill: 'none',
            ...props
        })
    }

    else if (color) {
        if (color === 'none') {
            return _fn('red')
        } else {
            // 彩色
            let colors = _colors(color, matrix.length, alpha)
            return _fn(colors)
        }

    }
}